package locadora.negocio.produtos;

import java.io.Serializable;
import java.util.Date;




import locadora.negocio.Buscavel;
import locadora.negocio.pessoas.Cliente;
import miscelanea.Data;

public class Item implements Serializable, Buscavel{
	
	private static final long serialVersionUID = 1L;
	public static final int TAM_MAX_TIT  =   64;
	public static final int TAM_MAX_DESC = 1024;
	
	private long	id;
	private String 	titulo;
	private int 	numMidias;
	private Data 	anoLancamento;
	private String 	descricao;
	private float	custo;
	private float	valorAluguel;
	private String  locador;
	private Data	dataLocacao;
	private Data	dataDevolucao;
	
	/**
	 * Instancia um objeto do tipo Item
	 * @param titulo título do Item
	 * @param numMidias número de mídias contidas em cada Item
	 * @param anoLancamento ano de lançamento
	 * @param descricao descrição detalhada do produto
	 * @param custo custo de compra do produto
	 * @param valorAluguel valor de locação
	 * @throws Exception
	 */
	public Item(String titulo, int numMidias, Data anoLancamento, String descricao, float custo, float valorAluguel) throws Exception{
		this.titulo = validaTitulo(titulo);
		this.numMidias = validaMidias(numMidias);
		this.anoLancamento = anoLancamento;
		this.descricao = limitaTamanhoDescricao(descricao);
		this.custo = custo;
		this.valorAluguel = valorAluguel;
		this.locador = null;
		this.dataLocacao = null;
		this.dataDevolucao = null;
		
		this.id = (new Date()).getTime();
	}
	
	/**
	 * Define o locador deste Item
	 * @param cliente locador
	 */
	public void setLocador(Cliente cliente){
		this.locador = cliente.getChave();
	}
	
	/**
	 * Retorna a data de locação
	 * @return data de locação
	 */
	public Data getDataLocacao(){
		return this.dataLocacao;
	}
	
	/**
	 * Define a data de locação
	 * @param data data de locação
	 */
	public void setDataLocacao(Data data){
		this.dataLocacao = data;
	}
	
	/**
	 * Retorna a data de devolução
	 * @return data de devolução
	 */
	public Data getDataDevolucao(){
		return this.dataDevolucao;
	}
	
	/**
	 * Define a data de devolução
	 * @param data data de devolução
	 */
	public void setDataDevolucao(Data data){
		this.dataDevolucao = data;
	}
	
	/**
	 * Retorna um ponteiro para o objeto do locador deste item
	 * @return ponteiro para um objeto do tipo Cliente
	 */
	public String getLocador(){
		return this.locador;
	}
	
	/**
	 * Retorna o valor de locação do Item
	 * @return valor de locação diária
	 */
	public float getValorAluguel(){
		return this.valorAluguel;
	}
	
	/**
	 * Retorna o título do Item
	 * @return título
	 */
	public String getTitulo() {
		return titulo;
	}

	/**
	 * Retorna o número de mídias contidas neste Item
	 * @return número de mídias
	 */
	public int getNumMidias() {
		return numMidias;
	}

	/**
	 * Retorna o ano de lançamento do título
	 * @return ano de lançamento
	 */
	public Data getAnoLancamento() {
		return anoLancamento;
	}

	/**
	 * Retorna uma descrição textual do conteúdo do Item
	 * @return descrição do Item
	 */
	public String getDescricao() {
		return descricao;
	}

	/**
	 * Retorna o custo de aquisição do Item
	 * @return
	 */
	public float getCusto() {
		return custo;
	}

	/**
	 * Retorna o parâmetro de entrada limitado a TAM_MAX_DESC caracteres ou null caso o parâmetro possua este valor
	 * @param descricao descrição do produto
	 * @return descrição do produto ou null
	 */
	protected String limitaTamanhoDescricao(String descricao) {
		String resultado = null;
		if(descricao != null){
			int tamanho = descricao.length();
			if(tamanho > TAM_MAX_DESC)
				tamanho = TAM_MAX_DESC;
			resultado = descricao.substring(0, tamanho);
		}
		return resultado;
	}

	/**
	 * Verifica se o número de mídias deste Item é valido
	 * @param numMidias número de mídias
	 * @return o mesvo valor da entrada
	 * @throws Exception mensagem indicando o erro
	 */
	protected int validaMidias(int numMidias) throws Exception {
		if(numMidias > 0)
			return numMidias;
		else
			throw new Exception("Número de mídias inválido!!");
	}
	
	/**
	 * Retorna o parâmetro de entrada limitado a TAM_MAX_DESC caracteres
	 * @param titulo título do Item
	 * @return mesmo parâmetro de entrada ou null
	 * @throws Exception caso um texto para o título não seja provido
	 */
	protected String validaTitulo(String titulo) throws Exception {
		String resultado = null;
		if(titulo != null){
			int tamanho = titulo.length();
			if(tamanho > TAM_MAX_TIT)
				tamanho = TAM_MAX_TIT;
			resultado = titulo.substring(0, tamanho);
		}else{
			throw new Exception("Todo item deve possuir um título!!");
		}
		return resultado;
	}
	
	/**
	 * Descrição em String para o objeto
	 */
	public String toString(){
		
		return "\n ID: " + this.id + "\n Título: " + this.titulo + "\n Número de mídias: " + this.numMidias + "\n Lançamento: " + this.anoLancamento + "\n Descrição: " + this.descricao + "\n Custo: R$ " + this.custo + "\n Aluguel: R$ " + this.valorAluguel + "\n";
	}
	
	/**
	 * Retorna uma descrição em String da chave única do Item
	 * @return chave do Item
	 */
	public String getChave() {
		return (this.id + "");
	}
	
	public void atualizar(String titulo, int numMidias, Data anoLancamento, String descricao, float custo, float valorAluguel, String chaveCliente, Data dataLocacao, Data dataDevolucao) throws Exception{
		if(this.titulo != titulo)
			this.titulo = validaTitulo(titulo);
		if(this.numMidias != numMidias)
			this.numMidias = validaMidias(numMidias);
		if(this.anoLancamento != anoLancamento)
			this.anoLancamento = anoLancamento;
		if(this.descricao != descricao)
			this.descricao = limitaTamanhoDescricao(descricao);
		if(this.custo != custo)
			this.custo = custo;
		if(this.valorAluguel != valorAluguel)
			this.valorAluguel = valorAluguel;
		if(this.dataLocacao != dataLocacao)
			this.dataLocacao = dataLocacao;
		if(this.dataDevolucao != dataDevolucao)
			this.dataDevolucao = dataDevolucao;
		if(this.locador != chaveCliente)
			this.locador = chaveCliente;
	}
}
